package com.utils.report;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;
import com.utils.Ret;


/**
 * apache fileupload 文件上传实现
 * @author mapei
 *
 */
public class FileUpload extends FileUploadBase{
	private HttpServletRequest request;
	private String savePath;//文件默认保存目录
	private long maxSize = 4194304;// 上传文件大小限制 默认4M 4 * 1024 * 1024;
	private Ret ret = new Ret();//返回消息
	private List<Map<String,String>> saveUrls=new ArrayList<Map<String,String>>();//文件保存路径列表
	private Map<String,String> params = new HashMap<String, String>();//form表单参数
	private String fileExt="file";//文件后缀检查
	
	public FileUpload() {
	}

	public FileUpload(HttpServletRequest request, String savePath) {
		this.request = request;
		this.savePath = savePath;
	}
	
	public FileUpload(HttpServletRequest request, String savePath,
			Ret ret) {
		this.request = request;
		this.savePath = savePath;
		this.ret = ret;
	}
	
	public FileUpload(HttpServletRequest request, String savePath, long maxSize,
			Ret ret) {
		this.request = request;
		this.savePath = savePath;
		this.maxSize = maxSize;
		this.ret = ret;
	}
	
	public FileUpload(HttpServletRequest request, String savePath,
			long maxSize, Ret ret, String fileExt) {
		this.request = request;
		this.savePath = savePath;
		this.maxSize = maxSize;
		this.ret = ret;
		this.fileExt = fileExt;
	}

	@Override
	public void upload() {
		try {
			if(!ServletFileUpload.isMultipartContent(this.request)){
				this.ret.setStatusCode("300");
				this.ret.setMessage("请选择文件。");
				return;
			}
			//检查目录
			File uploadDir = new File(this.savePath);
			if(!uploadDir.isDirectory()){
				this.ret.setStatusCode("300");
				this.ret.setMessage("上传指定目录不存在。");
				return;
			}
			//检查目录写权限
			if(!uploadDir.canWrite()){
				this.ret.setStatusCode("300");
				this.ret.setMessage("上传目录没有写权限。");
				return;
			}

			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			upload.setHeaderEncoding("UTF-8");
			List items = upload.parseRequest(request);
			Iterator itr = items.iterator();
			//第一次遍历获取表单元素
			while (itr.hasNext()) {
				FileItem item = (FileItem) itr.next();
				String fileName = item.getName();
				if(item.isFormField()){//如果是表单元素
					this.params.put(item.getFieldName(), item.getString("UTF-8"));
				}
			}
			String dirName = fileExt;
			if (StringUtils.isEmpty(dirName)) {
				dirName = "file";
			}
			if(!getExtMap().containsKey(dirName)){
				this.ret.setStatusCode("300");
				this.ret.setMessage("目录名不正确。");
				return;
			}
			//创建文件夹
			savePath += dirName + "/";
			File saveDirFile = new File(savePath);
			if (!saveDirFile.exists()) {
				saveDirFile.mkdirs();
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			String ymd = sdf.format(new Date());
			savePath += ymd + "/";
			File dirFile = new File(savePath);
			if (!dirFile.exists()) {
				dirFile.mkdirs();
			}
			
			Map<String,String> saveUrl=null;//获取文件保存信息
			Iterator itr2 = items.iterator();
			while (itr2.hasNext()) {
				saveUrl = new HashMap<String, String>();
				FileItem item = (FileItem) itr2.next();
				String fileName = item.getName();
				saveUrl.put("fileName", fileName);//.substring(fileName.lastIndexOf("\\")+1);
				saveUrl.put("fieldName",item.getFieldName());
				if(!item.isFormField() && item.getSize()>0){
					//检查文件大小
					if(item.getSize() > maxSize){
						this.ret.setStatusCode("300");
						String max_msg = "";
						if(maxSize < 1048576){
							max_msg = this.maxSize/1024 + "kb";
						}else{
							max_msg = this.maxSize/1024/1024 + "M";
						}
						this.ret.setMessage("上传文件大小超过"+max_msg+"限制。");
						return;
					}
					//检查扩展名
					String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
					if(!Arrays.<String>asList(getExtMap().get(dirName).split(",")).contains(fileExt)){
						this.ret.setStatusCode("300");
						this.ret.setMessage("上传文件扩展名是不允许的扩展名。\n只允许" + getExtMap().get(dirName) + "格式。");
						return;
					}

					SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
					String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
					try{
						File uploadedFile = new File(savePath, newFileName);
						item.write(uploadedFile);
					}catch(Exception e){
						this.ret.setStatusCode("300");
						this.ret.setMessage("上传文件失败。"+e.getMessage());
						return;
					}
					saveUrl.put("saveUrl", this.savePath + newFileName);
					this.saveUrls.add(saveUrl);
				}
			}
		} catch (Exception e) {
			this.ret.setStatusCode("300");
			this.ret.setMessage("上传文件失败。"+e.getMessage());
			return;
		}	
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public long getMaxSize() {
		return maxSize;
	}

	public void setMaxSize(long maxSize) {
		this.maxSize = maxSize;
	}

	public Ret getRet() {
		return ret;
	}

	public void setRet(Ret ret) {
		this.ret = ret;
	}

	public List<Map<String, String>> getSaveUrls() {
		return saveUrls;
	}

	public void setSaveUrls(List<Map<String, String>> saveUrls) {
		this.saveUrls = saveUrls;
	}

	public Map<String, String> getParams() {
		return params;
	}

	public String getFileExt() {
		return fileExt;
	}

	public void setFileExt(String fileExt) {
		this.fileExt = fileExt;
	}
}
